//
//  ImageEditContainer.swift
//  TemplateImageEditDemo
//
//  Created by liguandong on 2024/4/11.
//

import Foundation
import UIKit
import SnapKit
class TemplateEditContainer2: UIView {
    // 点击非活跃视图时的闭包
    var SetEditBlock: (() -> Void)?
    // 删除视图的闭包
    var RemoveViewBlock: ((TemplateImageView2) -> Void)?
    
    
    private lazy var editContainer: UIView = {
        let v = UIView()
        v.backgroundColor = .yellow
        v.alpha = 0.4
        return v
    }()
    
    lazy var imageBorder: UIView = {
        let v = UIView(frame: .zero)
        v.backgroundColor = .blue
        v.layer.borderColor = UIColor.red.cgColor
        v.layer.borderWidth = 2
        v.layer.cornerRadius = 6
        return v
    }()
    
    private lazy var removeCtrl: UIImageView = {
//        let v = UIImageView(frame: CGRect(x: 0, y: 0, width: Ctrl_Radius * 2, height: Ctrl_Radius * 2))
        let v = UIImageView()
        v.isUserInteractionEnabled = true
        v.image = UIImage(named: "AddView_close")
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(removeCtrlTapGesture(_:)))
        v.addGestureRecognizer(tapGesture)
        return v
    }()
    
    private lazy var rotateCtrl: UIImageView = {
//        let v = UIImageView(frame: CGRect(x: frame.size.width - Ctrl_Radius * 2, y: frame.size.height - Ctrl_Radius * 2, width: Ctrl_Radius * 2, height: Ctrl_Radius * 2))
        let v = UIImageView()
        v.image = UIImage(named: "AddView_rotate")
        v.isUserInteractionEnabled = true
        v.autoresizingMask = [.flexibleLeftMargin, .flexibleBottomMargin]
        let panGesture = UIPanGestureRecognizer(target: self, action: #selector(rotateCtrlPanGesture(_:)))
        v.addGestureRecognizer(panGesture)
        return v
    }()
    
//    private lazy var tapGesture: UITapGestureRecognizer = {
//        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(tapGestureAction(_:)))
//        return tapGesture
//    }()
//
    private lazy var panGesture: UIPanGestureRecognizer = {
        let panGesture = UIPanGestureRecognizer(target: self, action: #selector(panGestureAction(_:)))
        return panGesture
    }()
    
    private lazy var pinchGesture: UIPinchGestureRecognizer = {
        let pinchGesture = UIPinchGestureRecognizer(target: self, action: #selector(pinchAction(_:)))
        pinchGesture.delegate = self
        return pinchGesture
    }()

    private lazy var rotateGesture: UIRotationGestureRecognizer = {
        let rotateGesture = UIRotationGestureRecognizer(target: self, action: #selector(rotateAction(_:)))
//        let rotateGesture = UIRotationGestureRecognizer()
        rotateGesture.delegate = self
        return rotateGesture
    }()

    override init(frame: CGRect) {
        super.init(frame: frame)
        addSubview(editContainer)
        editContainer.addSubview(imageBorder)
        editContainer.addSubview(removeCtrl)
        editContainer.addSubview(rotateCtrl)
        imageBorder.snp.makeConstraints { make in
            make.left.equalToSuperview().offset(Ctrl_Radius)
            make.right.equalToSuperview().offset(-Ctrl_Radius)
            make.top.equalToSuperview().offset(Ctrl_Radius)
            make.bottom.equalToSuperview().offset(-Ctrl_Radius)
        }
        removeCtrl.snp.makeConstraints { make in
            make.width.equalTo(Ctrl_Radius * 2)
            make.height.equalTo(Ctrl_Radius * 2)
            make.centerX.equalTo(imageBorder.snp.left)
            make.centerY.equalTo(imageBorder.snp.top)
        }
        rotateCtrl.snp.makeConstraints { make in
            make.width.equalTo(Ctrl_Radius * 2)
            make.height.equalTo(Ctrl_Radius * 2)
            make.centerX.equalTo(imageBorder.snp.right)
            make.centerY.equalTo(imageBorder.snp.bottom)
        }
        isHidden = true
        
        addGestureRecognizer(panGesture)
        addGestureRecognizer(pinchGesture)
        addGestureRecognizer(rotateGesture)
        
        
    }
    
    @available(*, unavailable)
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    
    private var editImageView : TemplateImageView2?
    func startEdit(imageView: TemplateImageView2) {
        if editImageView == imageView {
            return
        }
        self.editImageView = imageView

//        let imageFrame =  imageView.originFrame
//        editContainer.center = imageView.center
//        editContainer.frame  = CGRect(x:imageFrame.origin.x - Ctrl_Radius, y: imageFrame.origin.y - Ctrl_Radius, width: imageFrame.width + 2 * Ctrl_Radius, height: imageFrame.height + 2 * Ctrl_Radius)
//        editContainer.layoutIfNeeded()
        
        
        editContainer.snp.remakeConstraints { make in
            make.left.equalTo(imageView.snp.left).offset(-Ctrl_Radius)
            make.right.equalTo(imageView.snp.right).offset(Ctrl_Radius)
            make.top.equalTo(imageView.snp.top).offset(-Ctrl_Radius)
            make.bottom.equalTo(imageView.snp.bottom).offset(Ctrl_Radius)
        }
        
        editContainer.transform = imageView.transform
        removeCtrl.transform = .identity
        rotateCtrl.transform = .identity
        isHidden = false
    }
    
    func endEdit(){
        self.editImageView = nil
        removeCtrl.transform = .identity
        rotateCtrl.transform = .identity
        isHidden = true
    }
    
    
    // MARK: - Gesture Recognizer Actions
    
//    @objc private func tapGestureAction(_ tapGesture: UITapGestureRecognizer) {
//        if !isEditing {
//            SetEditBlock?()
//            isEditing = true
//        }
//    }
    
    @objc func rotateAction(_ rotateGesture: UIRotationGestureRecognizer) {
        guard rotateGesture.numberOfTouches > 1 else {
            return
        }
        editContainer.transform = CGAffineTransformRotate(editContainer.transform, rotateGesture.rotation)
        editImageView?.transform = editContainer.transform
        rotateGesture.rotation = 0
    }
    
    @objc private func panGestureAction(_ panGesture: UIPanGestureRecognizer) {
        guard panGesture.state == .changed else { return }
        guard panGesture.numberOfTouches <= 1 else {
            panGesture.setTranslation(.zero, in: superview)
            return
        }
        let translation = panGesture.translation(in: superview)
        
        editContainer.center = CGPoint(x: editContainer.center.x + translation.x, y: editContainer.center.y + translation.y)
        editImageView?.center = editContainer.center
        
        panGesture.setTranslation(.zero, in: superview)
    }
    
    @objc private func pinchAction(_ pinchGesture: UIPinchGestureRecognizer) {
        guard pinchGesture.numberOfTouches > 1 else { return }
        let scale = pinchGesture.scale
        if scale < 1 && editContainer.frame.size.width <= editImageView!.originalWidth / 2 {
            // Do nothing when zooming in to half the original width
        } else {
            editContainer.transform = editContainer.transform.scaledBy(x: scale, y: scale)
            editImageView?.transform = editContainer.transform
            fitCtrlScaleX(scaleX: scale, scaleY: scale)
        }

        pinchGesture.scale = 1
    }

    
    private var lastCtrlPoint: CGPoint = .zero
    @objc private func rotateCtrlPanGesture(_ panGesture: UIPanGestureRecognizer) {
        guard panGesture.state != .began else {
            //这两个转化是不一样的，但是没必要用这个
//            lastCtrlPoint = convert(rotateCtrl.center, to: superview)
//            lastCtrlPoint = editContainer.convert(rotateCtrl.center, to: editContainer.superview)
            
            lastCtrlPoint = panGesture.location(in: superview)
            debugPrint("rotateCtrl.center \(rotateCtrl.center)")
            debugPrint("convert rotateCtrl.center \(lastCtrlPoint))")
            return
        }

        guard panGesture.state != .ended else { return }
        let ctrlPoint = panGesture.location(in: superview)
        scaleViewWithCtrlPoint(ctrlPoint)
        rotateViewWithCtrlPoint(ctrlPoint)
        lastCtrlPoint = ctrlPoint
    }
    
    @objc private func removeCtrlTapGesture(_ tapGesture: UITapGestureRecognizer) {
        if editImageView != nil {
            RemoveViewBlock?(editImageView!)
        }
        endEdit()
//        removeFromSuperview()
    }
    
    // MARK: - Private Methods
    
    private func fitCtrlScaleX(scaleX: CGFloat, scaleY: CGFloat) {
        removeCtrl.transform = removeCtrl.transform.scaledBy(x: 1 / scaleX, y: 1 / scaleY)
        rotateCtrl.transform = rotateCtrl.transform.scaledBy(x: 1 / scaleX, y: 1 / scaleY)
    }
    
    private func distanceWithStartPoint(_ start: CGPoint, endPoint end: CGPoint) -> CGFloat {
        let x = start.x - end.x
        let y = start.y - end.y
        return sqrt(x * x + y * y)
    }
 
    private func scaleViewWithCtrlPoint(_ ctrlPoint: CGPoint) {
      
        let preDistance = distanceWithStartPoint(editContainer.center, endPoint: lastCtrlPoint)
        let newDistance = distanceWithStartPoint(editContainer.center, endPoint: ctrlPoint)
        let scale = newDistance / preDistance

        if scale < 1 && editContainer.frame.size.width <= editImageView!.originalWidth / 2 {
            // 当缩小到初始化宽高的一半时，停止缩小
        } else {
            editContainer.transform = editContainer.transform.scaledBy(x: scale, y: scale)
            editImageView?.transform = editContainer.transform
            fitCtrlScaleX(scaleX: scale, scaleY: scale)
        }
    }

    private func rotateViewWithCtrlPoint(_ ctrlPoint: CGPoint) {
        let newCenter = ctrlPoint
        let parentCenter = editContainer.center
        let angle = atan2(parentCenter.y - newCenter.y, newCenter.x - parentCenter.x)
        let lastAngle = atan2(parentCenter.y - lastCtrlPoint.y, lastCtrlPoint.x - parentCenter.x)
        let rotationAngle = -angle + lastAngle
        editContainer.transform = editContainer.transform.rotated(by: rotationAngle)
        editImageView?.transform = editContainer.transform
        
//        var newCenter = ctrlPoint
//        let angle = atan2(center.y - newCenter.y, newCenter.x - center.x)
//        let lastAngle = atan2(center.y - lastCtrlPoint.y, lastCtrlPoint.x - center.x)
//        let rotationAngle = -angle + lastAngle
        
        debugPrint("rotationAngle : \(rotationAngle)")
        debugPrint("lastCtrlPoint : \(lastCtrlPoint)")
        debugPrint("ctrlPoint : \(ctrlPoint)")
    }
    
    
}

// MARK: - UIGestureRecognizerDelegate

extension TemplateEditContainer2: UIGestureRecognizerDelegate {
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return true
    }
    
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
        if gestureRecognizer.view == self {
            let p = touch.location(in: self)
            if rotateCtrl.frame.contains(p) {
                return false
            }
        }
        return true
    }
}
